package com.moon.back.service.impl;


import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.util.ObjectUtil;
import com.moon.back.constant.RedisConstant;
import com.moon.back.constant.UserContrant;
import com.moon.back.context.UserContext;
import com.moon.back.dao.FileNodeDao;
import com.moon.back.dao.UserDao;
import com.moon.back.entity.User;
import com.moon.back.entity.UserInfo;
import com.moon.back.entity.dto.UserDto;
import com.moon.back.entity.file.FileNode;
import com.moon.back.entity.vo.UserInfoVo;
import com.moon.back.service.IUserService;
import com.moon.back.util.HdfsUtil;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.core.SQLManager;
import org.redisson.api.RBucket;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service

public class UserServiceImpl implements IUserService {

    private static String key = "yonqin";
    @Autowired
    private UserDao userDao;
    @Autowired
    private SQLManager sqlManager;
    @Autowired
    private HdfsUtil hdfsUtil;
    @Autowired
    private RedissonClient  redissonClient;
    @Autowired
    private FileNodeDao fileNodeDao;

    @Override
    public SaResult login(UserDto userDto) {
        List<User> res = userDao.createQuery()
                .andEq("username",
                        userDto.getUsername()).select();

        if(ObjectUtil.isNull(res) ||res.isEmpty()){
            return SaResult.error("不存在该用户");
        }
        UserInfo userInfo = new UserInfo();
        User user = res.get(0);
        String pwd = SaSecureUtil.aesDecrypt(key, user.getPassword());
        log.info("密码: {}",pwd);

        if(!userDto.getPassword().equals(pwd)){
            return SaResult.error("密码错误");
        }
        // 登录状态更新
        StpUtil.login(user.getId());
        // 获取 token 信息
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        log.info("token: {}" ,tokenInfo.getTokenValue());
        double fileCapacity = fileNodeDao.getFileCapacity( "%"+user.getUsername()+"%" );
        // 默认 1G
        fileCapacity  = fileCapacity/(1024*1024);
        log.info("fileCapacity: {}" ,fileCapacity);
        BeanUtils.copyProperties(user,userInfo);
        userInfo.setCapacity(Double.parseDouble(String.format("%.3f",fileCapacity)));
        //  将用户数据 保存到 redis中
        RBucket<UserInfo> bucket = redissonClient.getBucket(tokenInfo.getTokenValue());
        // 设置 redis 的过期时间
        bucket.set(userInfo,UserContrant.userLoginCacheExpire,TimeUnit.SECONDS);
        // 每次上传成功后都应该更新 文件夹的容量数据

        return SaResult.data(tokenInfo);
    }

    // 登出
    @Override
    public SaResult logout(Integer loginId,HttpServletRequest request) {
        String header = request.getHeader("dev-moon-token");

        RScoredSortedSet<String> sortedSet = redissonClient.getScoredSortedSet(RedisConstant.DEV_INLINE_NUM);
        // 删除 过期 的成员
        boolean remove = sortedSet.remove(header);
        StpUtil.logout(loginId);

        return  SaResult.ok(header);
    }

    @Override
    public SaResult register(UserDto userDto) {
        User user = new User ();
        // 判断用户名是否重复
        List<User> username = userDao.createQuery().andEq("username", userDto.getUsername()).select();
        if(!username.isEmpty()){
            return SaResult.error("用户名已存在");
        }
        user.setUsername(userDto.getUsername());
        user.setPassword(userDto.getPassword());
        user.setEmail(userDto.getEmail());
        try{ // 判断是否注册成功
            // 实现 密码 加密user.setUserId(1);
            String password = user.getPassword();
            // AES/ECB/PKCS5Padding
            String s = SaSecureUtil.aesEncrypt(key, password);
            user.setPassword(s);

            userDao.insert(user);
            //  创建 hadoop的网盘
            hdfsUtil.mkdir(userDto.getUsername());
            // 创建 mysql数据表的username文件夹
            FileNode fileNode =   FileNode.builder().build();
            fileNode.setFileName(userDto.getUsername());
            fileNode.setFileSize(0.0);
            fileNode.setIsDirectory(Boolean.TRUE);
            fileNode.setFileType(0);
            fileNode.setReplication(3);
            fileNode.setFilePath("/"+ userDto.getUsername());

            fileNodeDao.insert(fileNode);
        }catch(Exception e){
            e.printStackTrace();
            return SaResult.error(e.getMessage());
        }
        // 注册成功的标准
        return SaResult.ok("注册成功");
    }

    @Override
    public SaResult getUserInfo(HttpServletRequest request){

        UserInfo userInfo = UserContext.getUserInfo();
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo,userInfoVo);

        return SaResult.data(userInfoVo);
    }


}
